package top.lshaci.framework.common.model;

import lombok.Getter;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * Web controller json response<br><br>
 *
 * <b>0.0.4: </b> Add method: successMessage and message; Change the name of the params field to otherData<br>
 * <b>1.0.5: </b> Move form framework web module to framework common module
 * <b>1.0.9: </b> 修改方法名
 *
 * @author lshaci
 * @version 1.0.9
 * @since 0.0.1
 */
public class JsonResponse<R> implements Serializable {

    private static final long serialVersionUID = 7574078101944305355L;

    /**
     * 默认错误码
     */
    private static final int DEFAULT_ERROR_CODE = 500_0_00;

    /**
     * 默认错误消息
     */
    private static final String DEFAULT_ERROR_MESSAGE = "未知异常, 请联系管理员";
    /**
     * 默认成功消息
     */
    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

    /**
     * 状态信息; true: 成功, false: 失败
     */
    @Getter
    private boolean status;

    /**
     * 响应码
     */
    @Getter
    private int code;

    /**
     * 响应消息
     */
    @Getter
    private String message;

    /**
     * 需要返回的数据
     */
    @Getter
    private R data;

    /**
     * 返回添加的额外数据
     */
    @Getter
    private Map<String, Object> otherData = new HashMap<>();

    /**
     * Build a json response
     *
     * @return json response
     */
    public static <R> JsonResponse<R> build() {
        return new JsonResponse<>();
    }

    /**
     * 响应错误
     * <pre>
     * {
     *     "code":500,
     *     "status:false,
     *     "message":"未知异常, 请联系管理员"
     * }
     * </pre>
     *
     * @return 响应
     */
    public static <R> JsonResponse<R> error() {
        return error(DEFAULT_ERROR_MESSAGE);
    }

    /**
     * 响应错误
     * <pre>
     * {
     *     "code":500,
     *     "status:false,
     * }
     * </pre>
     *
     * @param message 错误消息
     * @return 响应
     */
    public static <R> JsonResponse<R> error(String message) {
        return error(DEFAULT_ERROR_CODE, message);
    }

    /**
     * 响应错误
     *
     * @param code    错误代码
     * @param message 错误消息
     * @return 响应
     */
    public static <R> JsonResponse<R> error(int code, String message) {
        final JsonResponse<R> jsonResponse = build();
        jsonResponse.status = false;
        jsonResponse.code = code;
        jsonResponse.message = message;
        return jsonResponse;
    }

    /**
     * 响应成功
     * <pre>
     * {
     *     "code":0,
     *     "status:true,
     *     "message":"success"
     * }
     * </pre>
     *
     * @return 响应
     */
    public static <R> JsonResponse<R> ok() {
        final JsonResponse<R> jsonResponse = build();
        jsonResponse.status = true;
        jsonResponse.message = DEFAULT_SUCCESS_MESSAGE;
        return jsonResponse;
    }

    /**
     * 响应成功数据
     *
     * @param data 数据
     * @param <R>  数据类型
     * @return 响应
     */
    public static <R> JsonResponse<R> ok(R data) {
        final JsonResponse<R> jsonResponse = ok();
        jsonResponse.data = data;
        return jsonResponse;
    }

    /**
     * 响应成功消息
     *
     * @param message 消息
     * @return 响应
     */
    public static <R> JsonResponse<R> okMsg(String message) {
        final JsonResponse<R> jsonResponse = ok();
        jsonResponse.message = message;
        return jsonResponse;
    }

    /**
     * 响应数据
     *
     * @param data 数据
     * @return 响应
     */
    public JsonResponse<R> data(R data) {
        this.data = data;
        return this;
    }

    /**
     * 响应数据
     *
     * @param map 数据
     * @return 响应
     */
    public JsonResponse<R> otherData(Map<String, Object> map) {
        this.otherData.putAll(map);
        return this;
    }

    /**
     * 响应数据
     *
     * @param key   数据键
     * @param value 数据值
     * @return 响应
     */
    public JsonResponse<R> otherData(String key, Object value) {
        this.otherData.put(key, value);
        return this;
    }

    /**
     * 响应消息
     *
     * @param message 消息
     * @return 响应
     */
    public JsonResponse<R> message(String message) {
        this.message = message;
        return this;
    }

    /**
     * 响应码
     *
     * @param code 响应码
     * @return 响应
     */
    public JsonResponse<R> code(int code) {
        this.code = code;
        return this;
    }

}
